/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hadss_adaptive_layout/hadss_adaptive_layout.dart';
import 'package:hadss_uni_input/hadss_uni_input.dart';
import 'package:just_audio_ohos/just_audio_ohos.dart';
import 'package:provider/provider.dart';
import 'package:samples/utils/audio_player_manager.dart';
import 'package:samples/utils/music_detail_bloc.dart';

import '../l10n/generated/app_localizations.dart';
import '../main.dart';

class MusicDetailPlayerPage extends StatefulWidget {
  final bool isNeedPlay;

  const MusicDetailPlayerPage({
    Key? key,
    this.isNeedPlay = false,
  }) : super(key: key);

  @override
  State<MusicDetailPlayerPage> createState() => _MusicDetailPlayerPageState();
}

class _MusicDetailPlayerPageState extends State<MusicDetailPlayerPage> {
  WidthBreakpoint screenType = WidthBreakpoint.xs;
  HeightBreakpoint screenHeightType = HeightBreakpoint.sm;
  double _scale = 1.0;
  final Offset _offset = Offset.zero;
  double processWidth = 0;
  AudioPlayerManager audioPlayerManager = AudioPlayerManager();
  double _rotation = 0.0;
  final GlobalKey _globalKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    if (widget.isNeedPlay) {
      audioPlayerManager.play();
    }
  }

  Future<void> seekToPosition(
      {required Duration duration,
      required Duration position,
      required double processWidth}) async {
    double totalWidth = getSeekBarWidth();
    double percent = processWidth / totalWidth;
    double totalDuration = duration.inSeconds.toDouble();
    double currentDuration = (totalDuration * percent).toDouble();
    audioPlayerManager.seek(Duration(seconds: currentDuration.toInt()));
  }

  @override
  Widget build(BuildContext context) {
    AppLocalizations il8n = AppLocalizations.of(context)!;
    return Consumer<RouteManager>(builder: (context, provider, child) {
      screenType = provider.widthBreakpoint;
      screenHeightType = provider.heightBreakpoint;
      return Consumer<MusicDetailBloc>(builder: (context, bloc, _) {
        if (bloc.logicalKey != null) {
          receivesKeyCode(logicalKey: bloc.logicalKey!);
        }
        return LayoutBuilder(builder: (context, constraints) {
          if (screenType == WidthBreakpoint.md &&
              screenHeightType != HeightBreakpoint.md) {
            return Container(
              color: Colors.transparent,
              child: buildOrientationLandscapeView(il8n),
            );
          }
          return Container(
            color: Colors.transparent,
            child: buildOrientationPortraitView(),
          );
        });
      });
    });
  }

  void receivesKeyCode({required LogicalKeyboardKey logicalKey}) {
    if (logicalKey == LogicalKeyboardKey.arrowLeft ||
        logicalKey == LogicalKeyboardKey.arrowRight) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        double totalWidth = getSeekBarWidth();
        //计算按一下快进或者后退5s，进度条需要走的宽度
        int? totalSeconds = audioPlayerManager.audioPlayer.duration?.inSeconds;
        double percent = 1.0;
        if (totalSeconds! > 5) {
          percent = 5 / totalSeconds;
        }
        if (logicalKey == LogicalKeyboardKey.arrowLeft) {
          _handleLeftArrowKey(totalWidth, percent);
        } else if (logicalKey == LogicalKeyboardKey.arrowRight) {
          _handleRightArrowKey(totalWidth, percent);
        }
      });
    } else if (logicalKey == LogicalKeyboardKey.arrowUp) {
      _handleUpArrowKey();
    } else if (logicalKey == LogicalKeyboardKey.arrowDown) {
      _handleDownArrowKey();
    } else if (logicalKey == LogicalKeyboardKey.space ||
        logicalKey == LogicalKeyboardKey.enter) {
      audioPlayerManager.audioPlayer.playing
          ? audioPlayerManager.pause()
          : audioPlayerManager.play();
    }
  }

  void _handleLeftArrowKey(double totalWidth, double percent) {
    if (processWidth > totalWidth * percent) {
      processWidth -= totalWidth * percent;
      audioPlayerManager.audioPlayer.seek(Duration(
          seconds: audioPlayerManager.audioPlayer.position.inSeconds - 5));
      if (!audioPlayerManager.audioPlayer.playerState.playing) {
        audioPlayerManager.audioPlayer.play();
      }
    } else {
      processWidth = 0;
      audioPlayerManager.audioPlayer.seek(const Duration(seconds: 0));
      audioPlayerManager.audioPlayer.pause();
    }
  }

  void _handleRightArrowKey(double totalWidth, double percent) {
    if (processWidth >= totalWidth - totalWidth * percent) {
      processWidth = totalWidth;
      audioPlayerManager.audioPlayer.pause();
    } else {
      processWidth += totalWidth * percent;
      audioPlayerManager.audioPlayer.seek(Duration(
          seconds: audioPlayerManager.audioPlayer.position.inSeconds + 5));
      if (!audioPlayerManager.audioPlayer.playerState.playing) {
        audioPlayerManager.audioPlayer.play();
      }
    }
  }

  void _handleUpArrowKey() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      processWidth = 0;
      audioPlayerManager.playPrevious();
      audioPlayerManager.seek(const Duration(seconds: 0));
      audioPlayerManager.audioPlayer.play();
    });
  }

  void _handleDownArrowKey() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      processWidth = 0;
      audioPlayerManager.playNext();
      audioPlayerManager.seek(const Duration(seconds: 0));
      audioPlayerManager.audioPlayer.play();
    });
  }

  Widget buildOrientationPortraitView() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Expanded(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              UnifiedGestureDetector(
                pointerOptions: const PointerOptions(
                  enablePinch: true,
                  enableRotate: true,
                ),
                onPinchStart: onPinchStart,
                onPinchUpdate: onPinchUpdate,
                onPinchEnd: onPinchEnd,
                onRotateStart: onRotateStart,
                onRotateUpdate: onRotateUpdate,
                onRotateEnd: onRotateEnd,
                child: Transform(
                  alignment: Alignment.center,
                  transform: Matrix4.identity()
                    ..translate(_offset.dx, _offset.dy)
                    ..rotateZ(_rotation)
                    ..scale(_scale),
                  child: Image.asset(
                    'lib/assets/images/title_page_1.png',
                  ),
                ),
              ),
              LayoutBuilder(
                builder: (context, constraints) {
                  if (screenType == WidthBreakpoint.xs ||
                      screenType == WidthBreakpoint.sm ||
                      screenType == WidthBreakpoint.md) {
                    return OrientationBuilder(
                      builder: (context, orientation) {
                        return buildSongTitleView();
                      },
                    );
                  }
                  return Container();
                },
              ),
            ],
          ),
        ),
        Column(
          children: [
            buildSlideProcessView(),
            buildPlayerMenuView(),
            buildBottomMenuView(),
          ],
        ),
      ],
    );
  }

  Widget buildOrientationLandscapeView(AppLocalizations il8n) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        Row(
          children: [
            Container(
              margin: const EdgeInsets.only(left: 20, right: 20),
              child: Image.asset(
                "lib/assets/images/singer_header.png",
                width: 48,
                height: 48,
              ),
            ),
            const SizedBox(
              width: 15,
            ),
            ValueListenableBuilder<Map>(
              valueListenable: audioPlayerManager.currentData,
              builder: (context, value, child) {
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      value["title"],
                      style: const TextStyle(
                          fontSize: 24,
                          fontWeight: FontWeight.w700,
                          color: Colors.white),
                    ),
                    Text(
                      value["subtitle"],
                      style: const TextStyle(
                        fontSize: 14,
                        color: Color(0x99ffffff),
                      ),
                    ),
                  ],
                );
              },
            ),
          ],
        ),
        Text(
          il8n.tips,
          style: TextStyle(fontSize: 24, color: Color(0x99ffffff)),
        ),
        Column(
          children: [
            buildSlideProcessView(),
            buildPlayerMenuView(),
          ],
        ),
      ],
    );
  }

  Widget buildSongTitleView() {
    return Container(
      margin: const EdgeInsets.only(left: 20, right: 20, bottom: 5),
      child: Row(
        children: [
          Expanded(
              child: ValueListenableBuilder<Map>(
            valueListenable: audioPlayerManager.currentData,
            builder: (context, value, child) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    value["title"],
                    style: const TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.w700,
                        color: Colors.white),
                  ),
                  Text(
                    value["subtitle"],
                    style: const TextStyle(
                      fontSize: 14,
                      color: Color(0x99ffffff),
                    ),
                  ),
                ],
              );
            },
          )),
          Image.asset(
            'lib/assets/images/collect_count.png',
            width: 30,
            height: 30,
          ),
        ],
      ),
    );
  }

  Widget buildSlideProcessView() {
    return StreamBuilder<PositionData>(
      stream: audioPlayerManager.positionDataStream,
      builder: (context, snapshot) {
        final positionData = snapshot.data;
        final Duration duration = positionData?.duration ?? Duration.zero;
        final Duration position = positionData?.position ?? Duration.zero;
        double processWidth =
            updateProcessWidth(duration: duration, position: position);
        return UnifiedGestureDetector(
          pointerOptions: const PointerOptions(
            enableRotate: false,
          ),
          onTap: onTap,
          onTapDown: onTapDown,
          onDragStart: onDragStart,
          onDragUpdate: onDragUpdate,
          onDragEnd: onDragEnd,
          child: Container(
            margin: const EdgeInsets.only(left: 20, right: 20, bottom: 12),
            key: _globalKey,
            child: Column(
              children: [
                Stack(
                  children: [
                    Container(
                      height: 6,
                      margin: const EdgeInsets.only(bottom: 5),
                      decoration: const BoxDecoration(
                        color: Color(0x33ffffff),
                        borderRadius: BorderRadius.all(Radius.circular(3)),
                      ),
                    ),
                    Container(
                      decoration: const BoxDecoration(
                        color: Color(0x99ffffff),
                        borderRadius: BorderRadius.all(Radius.circular(3)),
                      ),
                      height: 6,
                      width: processWidth,
                    ),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      _formatDuration("$position"),
                      style: const TextStyle(
                        fontSize: 10,
                        color: Color(0x99ffffff),
                      ),
                    ),
                    Text(
                      _formatDuration("$duration"),
                      style: const TextStyle(
                        fontSize: 10,
                        color: Color(0x99ffffff),
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        );
      },
    );
  }

  String _formatDuration(String duration) {
    RegExp exp = RegExp(r'((^0*[1-9]\d*:)?\d{2}:\d{2})\.\d+$');
    RegExpMatch? match = exp.firstMatch(duration);
    return match?.group(1) ?? duration;
  }

  Widget buildPlayerMenuView() {
    return Container(
      margin: const EdgeInsets.only(left: 20, right: 20, bottom: 20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Image.asset(
            "lib/assets/images/loop.png",
            width: 20,
            height: 20,
            color: const Color(0x99ffffff),
          ),
          buildPlayNext(false),
          buildPlayButton(),
          buildPlayNext(true),
          Image.asset(
            "lib/assets/images/menu.png",
            width: 20,
            height: 20,
            color: const Color(0x99ffffff),
          ),
        ],
      ),
    );
  }

  Widget buildBottomMenuView() {
    return Container(
      margin: const EdgeInsets.only(left: 20, right: 20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Image.asset(
            'lib/assets/images/broadcast.png',
            width: 20,
            height: 20,
          ),
          Image.asset(
            'lib/assets/images/bell.png',
            width: 20,
            height: 20,
          ),
          Image.asset(
            'lib/assets/images/download.png',
            width: 20,
            height: 20,
            color: const Color(0x99ffffff),
          ),
          Image.asset(
            'lib/assets/images/detail.png',
            width: 20,
            height: 20,
          ),
        ],
      ),
    );
  }

  Widget buildPlayButton() {
    return StreamBuilder<PlayerState>(
      stream: audioPlayerManager.audioPlayer.playerStateStream,
      builder: (context, snapshot) {
        final playerState = snapshot.data;
        final playing = playerState?.playing;
        if (playing == true) {
          return UnifiedGestureDetector(
            onTap: audioPlayerManager.audioPlayer.pause,
            child: Image.asset(
              "lib/assets/images/play_icon.png",
              width: 72,
              height: 72,
              fit: BoxFit.cover,
              color: Colors.white,
            ),
          );
        } else {
          return UnifiedGestureDetector(
            onTap: audioPlayerManager.audioPlayer.play,
            child: Image.asset(
              "lib/assets/images/pause_icon.png",
              width: 72,
              height: 72,
              fit: BoxFit.cover,
              color: Colors.white,
            ),
          );
        }
      },
    );
  }

  Widget buildPlayNext(bool isNext) {
    return isNext
        ? UnifiedGestureDetector(
            onTap: () {
              audioPlayerManager.playNext();
              audioPlayerManager.play();
            },
            child: Image.asset(
              "lib/assets/images/ic_public_play_next.png",
              width: 36,
              height: 36,
              color: Colors.white,
            ),
          )
        : UnifiedGestureDetector(
            onTap: () {
              audioPlayerManager.playPrevious();
              audioPlayerManager.play();
            },
            child: Image.asset(
              "lib/assets/images/ic_public_play_before.png",
              width: 36,
              height: 36,
              color: Colors.white,
            ),
          );
  }

  void onPinchStart(GestureEvent event) {}

  void onPinchUpdate(GestureEvent event) {
    // 根据滚轮方向调整缩放比例
    if (event.scale! < 0) {
      setState(() {
        _scale -= 0.005; // 向上滚，缩小
      });
    } else if (event.scale! > 0) {
      setState(() {
        _scale += 0.005; // 向下滚，放大
      });
    }
    // 限制缩放范围
    _scale = _scale.clamp(0.3, 1.0);
  }

  void onPinchEnd(GestureEvent event) {}

  void onDragStart(DragStartDetails detail) {}

  void onDragUpdate(DragUpdateDetails detail) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      double totalWidth = getSeekBarWidth();
      if (detail.localPosition.dx < totalWidth && detail.localPosition.dx > 0) {
        if (detail.localPosition.dx < 20) {
          processWidth = 0;
        } else if (detail.localPosition.dx > totalWidth - 20) {
          processWidth = totalWidth;
        } else {
          processWidth = detail.localPosition.dx;
        }
      }
      seekToPosition(
          duration: audioPlayerManager.audioPlayer.duration ?? Duration.zero,
          position: audioPlayerManager.audioPlayer.position,
          processWidth: processWidth);
    });
    if (mounted) {
      setState(() {});
    }
  }

  void onDragEnd(DragEndDetails detail) {
    seekToPosition(
        duration: audioPlayerManager.audioPlayer.duration ?? Duration.zero,
        position: audioPlayerManager.audioPlayer.position,
        processWidth: processWidth);
    setState(() {});
  }

  double updateProcessWidth(
      {required Duration duration, required Duration position}) {
    double processWidth = 0;
    double totalWidth = getSeekBarWidth();
    double totalSeconds = duration.inSeconds.toDouble();
    if (totalSeconds > 1) {
      double? currentSeconds = position.inSeconds.toDouble();
      if (currentSeconds > 1 && currentSeconds < totalSeconds) {
        double percent = position.inSeconds / totalSeconds;
        processWidth = totalWidth * percent;
      } else if (currentSeconds == totalSeconds) {
        processWidth = 0;
        audioPlayerManager.audioPlayer.seek(const Duration(seconds: 0));
        audioPlayerManager.audioPlayer.pause();
      } else if (currentSeconds == 0) {
        processWidth = 0;
      }
    }
    return processWidth;
  }

  void onRotateStart(GestureEvent event) {}

  void onRotateUpdate(GestureEvent event) {
    setState(() {
      _rotation = event.angle!;
    });
  }

  void onRotateEnd(GestureEvent event) {}

  void onTap() {}

  void onTapDown(TapDownDetails detail) {
    final totalWidth = getSeekBarWidth();
    if (detail.localPosition.dx > 20 &&
        detail.localPosition.dx - 20.0 < totalWidth) {
      processWidth = detail.localPosition.dx - 20.0;
      seekToPosition(
          duration: audioPlayerManager.audioPlayer.duration ?? Duration.zero,
          position: audioPlayerManager.audioPlayer.position,
          processWidth: processWidth);
    }
  }

  double getSeekBarWidth() {
    final renderBox =
        _globalKey.currentContext?.findRenderObject() as RenderBox?;
    double totalWidth = renderBox?.size.width ?? 0;
    return totalWidth > 0 ? totalWidth - 40 : totalWidth;
  }
}
